package org.example.utlis;

import cn.hutool.core.util.StrUtil;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 自定义工具类
 */
public class JoeDevUtils {


    /**
     * 压缩文件
     *
     * @param sourceFilePath 源文件路径
     * @param zipFilePath    压缩后文件存储路径
     * @param zipFilename    压缩文件名
     */
    public static void compressToZip(String sourceFilePath, String zipFilePath, String zipFilename) {
        File sourceFile = new File(sourceFilePath);
        File zipPath = new File(zipFilePath);
        if (!zipPath.exists()) {
            zipPath.mkdirs();
        }
        File zipFile = new File(zipPath + File.separator + zipFilename);
        try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile))) {
            writeZip(sourceFile, "", zos);
            //文件压缩完成后，删除被压缩文件
            boolean flag = deleteDir(sourceFile);
            //log.info("删除被压缩文件[" + sourceFile + "]标志：{}", flag);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage(), e.getCause());
        }
    }
    /**
     * 遍历所有文件，压缩
     *
     * @param file       源文件目录
     * @param parentPath 压缩文件目录
     * @param zos        文件流
     */
    public static void writeZip(File file, String parentPath, ZipOutputStream zos) {
        if (file.isDirectory()) {
            //目录
            parentPath += file.getName() + File.separator;
            File[] files = file.listFiles();
            for (File f : files) {
                writeZip(f, parentPath, zos);
            }
        } else {
            //文件
            try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {
                //指定zip文件夹
                ZipEntry zipEntry = new ZipEntry(parentPath + file.getName());
                zos.putNextEntry(zipEntry);
                int len;
                byte[] buffer = new byte[1024 * 10];
                while ((len = bis.read(buffer, 0, buffer.length)) != -1) {
                    zos.write(buffer, 0, len);
                    zos.flush();
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e.getMessage(), e.getCause());
            }
        }
    }

        /**
         * 删除文件夹
         *
         * @param dir
         * @return
         */
        public static boolean deleteDir(File dir) {
            if (dir.isDirectory()) {
                String[] children = dir.list();
                for (int i = 0; i < children.length; i++) {
                    boolean success = deleteDir(new File(dir, children[i]));
                    if (!success) {
                        return false;
                    }
                }
            }
            //删除空文件夹
            return dir.delete();
        }


        /**
         * 获取当前req
         * @return
         */
    public static HttpServletRequest getRequest(){
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }
    /**
     * 获取当前resp
     * @return
     */
    public static HttpServletResponse getResponse(){
        return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();
    }
    /**
     * 获取当前req访问地址
     * @return
     */
    public static String getRequestURI(){
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        return request.getRequestURI();
    }

    /**
     * 截取过长字符串
     * @param str
     * @param length
     * @return
     */
    public static String limitStr(String str,int length){
        if(StrUtil.isEmpty(str)){
            return str;
        }
        if(str.trim().length()>length){
            return str.trim().substring(0,length);
        }
        return str.trim();
    }

    /**
     * 压缩文件导出
     * @param srcFiles
     * @param zipFile
     */
    public static void zipFiles(File[] srcFiles, File zipFile) {
         // 判断压缩后的文件存在不，不存在则创建
         if (!zipFile.exists()) {
             try {
                    zipFile.getParentFile().mkdirs();
                     zipFile.createNewFile();
                 } catch (IOException e) {
                     e.printStackTrace();
                 }
         }
         // 创建 FileOutputStream 对象
         FileOutputStream fileOutputStream = null;
         // 创建 ZipOutputStream
         ZipOutputStream zipOutputStream = null;
         // 创建 FileInputStream 对象
         FileInputStream fileInputStream = null;

         try {
                 // 实例化 FileOutputStream 对象
                 fileOutputStream = new FileOutputStream(zipFile);
                 // 实例化 ZipOutputStream 对象
                 zipOutputStream = new ZipOutputStream(fileOutputStream);
                 // 创建 ZipEntry 对象
                 ZipEntry zipEntry = null;
                // 遍历源文件数组
                 for (int i = 0; i < srcFiles.length; i++) {
                         // 将源文件数组中的当前文件读入 FileInputStream 流中
                         fileInputStream = new FileInputStream(srcFiles[i]);
                         // 实例化 ZipEntry 对象，源文件数组中的当前文件
                         zipEntry = new ZipEntry(srcFiles[i].getName());
                         zipOutputStream.putNextEntry(zipEntry);
                         // 该变量记录每次真正读的字节个数
                         int len;
                         // 定义每次读取的字节数组
                         byte[] buffer = new byte[1024];
                         while ((len = fileInputStream.read(buffer)) > 0) {
                                 zipOutputStream.write(buffer, 0, len);
                             }
                     }
                 zipOutputStream.closeEntry();
                 zipOutputStream.close();
                 fileInputStream.close();
                 fileOutputStream.close();
             } catch (IOException e) {
                 e.printStackTrace();
             }

    }

    /**
     * 删除文件夹下的文件
     * @param dir
     * @return
     */
    public static boolean deleteDirectory(String dir) {
        // 如果dir不以文件分隔符结尾，自动添加文件分隔符
        if (!dir.endsWith(File.separator))
            dir = dir + File.separator;
        File dirFile = new File(dir);
        // 如果dir对应的文件不存在，或者不是一个目录，则退出
        if ((!dirFile.exists()) || (!dirFile.isDirectory())) {
            return false;
        }
        boolean flag = true;
        // 删除文件夹中的所有文件包括子目录
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            // 删除子文件
            if (files[i].isFile()) {
                flag = deleteFile(files[i].getAbsolutePath());
                if (!flag)
                    break;
            }
            // 删除子目录
            else if (files[i].isDirectory()) {
                flag = deleteDirectory(files[i].getAbsolutePath());
                if (!flag)
                    break;
            }
        }
        if (!flag) {
            return false;
        }
        // 删除当前目录
        if (dirFile.delete()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 删除单个文件
     *
     * @param fileName：要删除的文件的文件名
     * @return 单个文件删除成功返回true，否则返回false
     */
    public static boolean deleteFile(String fileName) {
        File file = new File(fileName);
        // 如果文件路径所对应的文件存在，并且是一个文件，则直接删除
        if (file.exists() && file.isFile()) {
            if (file.delete()) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }


    public static void clear(InputStream in, OutputStream out) {
        if(in!=null){
            try {
                in.close();
            } catch (IOException e) {
            }
        }
        if(out!=null){
            try {
                out.close();
            } catch (IOException e) {
            }
        }
    }

    public static void clear(OutputStream out) {
        if(out!=null){
            try {
                out.close();
            } catch (IOException e) {
            }
        }
    }
    public static void clear(InputStream in) {
        if(in!=null){
            try {
                in.close();
            } catch (IOException e) {
            }
        }
    }
}
